package com.triones.api.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.constant.EmailCodeTypeConstants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.email.EmailCodeVerifyUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.triones.api.entity.BankCardDO;
import com.triones.api.entity.CardholderDO;
import com.triones.api.entity.KycVerifyDO;
import com.triones.api.entity.bo.BankCardBO;
import com.triones.api.entity.bo.CardholderBodyBO;
import com.triones.api.entity.bo.KycVerifyBO;
import com.triones.api.entity.param.KycVerifyParams;
import com.triones.api.entity.vo.CardholderVO;
import com.triones.api.entity.vo.KycVerifyVO;
import com.triones.api.mapper.BankCardMapper;
import com.triones.api.mapper.CardholderMapper;
import com.triones.api.mapper.KycVerifyMapper;
import com.triones.api.service.KycVerifyService;
import com.triones.api.service.third.PhotonPayService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * kyc验证 -业务实现
 */
@Service
@RequiredArgsConstructor
public class KycVerifyServiceImpl implements KycVerifyService {

    private final KycVerifyMapper kycVerifyMapper;

    private final BankCardMapper bankCardMapper;

    private final PhotonPayService photonPayService;

    private final CardholderMapper cardholderMapper;

    @Override
    public Boolean checkIsKyc() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        boolean flag = false;
        KycVerifyDO kycVerifyDO = kycVerifyMapper.selectOne(new LambdaQueryWrapper<KycVerifyDO>().eq(KycVerifyDO::getUid, loginUser.getUserId())
            .orderByDesc(KycVerifyDO::getCreateTime).last("limit 1"));
        if (kycVerifyDO == null) {
            flag = true;
        } else {
            if ("0".equals(kycVerifyDO.getAuditStatus())) {
                throw new ServiceException("当前kyc验证等待审核，请勿重复提交！");
            } else if ("2".equals(kycVerifyDO.getAuditStatus())) {
                flag = true;
            }
        }
        return flag;
    }

    @Override
    public KycVerifyVO apiKycInfo() {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        return kycVerifyMapper.selectVoOne(new LambdaQueryWrapper<KycVerifyDO>().eq(KycVerifyDO::getUid, loginUser.getUserId())
            .orderByDesc(KycVerifyDO::getCreateTime).last("limit 1"));
    }

    @Override
    public boolean apiKycVerify(KycVerifyBO bo) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        EmailCodeVerifyUtils.emailCodeValid(EmailCodeTypeConstants.CW_EMAIL_KYC_VERIFY_CODE,bo.getEmail(),bo.getEmailCode());
        KycVerifyDO kycVerifyDO = kycVerifyMapper.selectOne(new LambdaQueryWrapper<KycVerifyDO>().eq(KycVerifyDO::getUid, loginUser.getUserId())
            .orderByDesc(KycVerifyDO::getCreateTime).last("limit 1"));
        if (kycVerifyDO != null) {
            if ("0".equals(kycVerifyDO.getAuditStatus())) {
                throw new ServiceException("当前kyc验证等待审核，请勿重复提交！");
            } else if ("1".equals(kycVerifyDO.getAuditStatus())) {
                throw new ServiceException("当前kyc验证审核通过，请勿重复提交！");
            }
        }
        KycVerifyDO saveDO = new KycVerifyDO();
        BeanUtil.copyProperties(bo,saveDO);
        saveDO.setUid(loginUser.getUserId());
        saveDO.setCreateTime(System.currentTimeMillis());
        return kycVerifyMapper.insert(saveDO) > 0;
    }

    @Override
    public TableDataInfo<KycVerifyVO> pageList(KycVerifyParams kycVerifyParams, PageQuery pageQuery) {
        Map<String, Object> params = kycVerifyParams.getParams();
        LambdaQueryWrapper<KycVerifyDO> lqw = new LambdaQueryWrapper<KycVerifyDO>();
        lqw.eq(StringUtils.isNotBlank(kycVerifyParams.getAuditStatus()),KycVerifyDO::getAuditStatus, kycVerifyParams.getAuditStatus());
        lqw.or(ObjectUtil.isNotEmpty(kycVerifyParams.getKeyword()),
            qw -> qw.like(KycVerifyDO::getLastName,kycVerifyParams.getKeyword()).or()
                .like(KycVerifyDO::getFirstName,kycVerifyParams.getKeyword()).or()
                .like(KycVerifyDO::getEmail,kycVerifyParams.getKeyword()).or()
                .like(KycVerifyDO::getPhoneAreaCode,kycVerifyParams.getKeyword()).or()
                .like(KycVerifyDO::getPhone,kycVerifyParams.getKeyword()).or()
                .like(KycVerifyDO::getCountry,kycVerifyParams.getKeyword()).or()
                .like(KycVerifyDO::getCity,kycVerifyParams.getKeyword())
        );
        lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
            KycVerifyDO::getCreateTime, params.get("beginTime"), params.get("endTime"));
        lqw.between(params.get("beginAuditTime") != null && params.get("endAuditTime") != null,
            KycVerifyDO::getAuditTime, params.get("beginTime"), params.get("endTime"));
        lqw.orderByDesc(KycVerifyDO::getCreateTime);
        Page<KycVerifyVO> result = kycVerifyMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    @Override
    public boolean audit(KycVerifyDO dto) {
        LoginUser loginUser = LoginHelper.getLoginUser();
        if (loginUser == null) {
            throw new ServiceException("当前用户退出登录!");
        }
        KycVerifyDO kycVerifyDO = kycVerifyMapper.selectById(dto.getId());
        if (kycVerifyDO == null) {
            throw new ServiceException("kyc验证信息不存在!");
        }
        if (!kycVerifyDO.getAuditStatus().equals("0")) {
            throw new ServiceException("kyc验证信息已审核，请勿重复审核!");
        }
        kycVerifyDO.setAuditStatus(dto.getAuditStatus());
        kycVerifyDO.setFailRemark(dto.getFailRemark());
        kycVerifyDO.setAuditUserId(loginUser.getUserId());
        kycVerifyDO.setAuditUserName(loginUser.getUsername());
        kycVerifyDO.setAuditTime(System.currentTimeMillis());
        kycVerifyMapper.updateById(kycVerifyDO);

        if ("1".equals(dto.getAuditStatus())) {
            //发送持卡人新增
            CardholderVO cardholderVO = cardholderMapper.selectVoOne(new LambdaQueryWrapper<CardholderDO>()
                    .eq(CardholderDO::getUid, kycVerifyDO.getUid())
                    .eq(CardholderDO::getStatus, "normal")
                    .orderByDesc(CardholderDO::getCreateTime));
            if (cardholderVO == null) {
                /**
                 * 发送新增用卡人请求
                 */
                CardholderBodyBO cardholderBodyBO = new CardholderBodyBO();
                BeanUtil.copyProperties(kycVerifyDO,cardholderBodyBO);
                cardholderBodyBO.setMobile(kycVerifyDO.getPhone());
                cardholderBodyBO.setMobilePrefix(kycVerifyDO.getPhoneAreaCode());
                Map addCardholderResponseMap = photonPayService.addCardholder(cardholderBodyBO);
                if (addCardholderResponseMap != null) {
                    CardholderDO cardholderDO = new CardholderDO();
                    BeanUtil.copyProperties(cardholderBodyBO,cardholderDO);
                    cardholderDO.setUid(kycVerifyDO.getUid());
                    cardholderDO.setCreateTime(System.currentTimeMillis());
                    cardholderDO.setCardholderId(Convert.toStr(addCardholderResponseMap.get("cardholderId")));
                    cardholderDO.setStatus(Convert.toStr(addCardholderResponseMap.get("status")));
                    cardholderDO.setCardholderReviewStatus(Convert.toStr(addCardholderResponseMap.get("cardholderReviewStatus")));
                    cardholderDO.setIdInfoRequirement(Convert.toStr(addCardholderResponseMap.get("idInfoRequirement")));
                    cardholderDO.setReason(Convert.toStr(addCardholderResponseMap.get("reason")));
                    cardholderMapper.insert(cardholderDO);
                }
            }

        }
        return true;
    }

    @Override
    public KycVerifyVO getInfo(Long id) {
        return kycVerifyMapper.selectVoById(id);
    }
}
